﻿using System;

namespace DataStore.Domain
{
    /// <summary>
    /// Address
    /// </summary>
    [Serializable]
    public class Address :IEquatable<Address>
    {
        public virtual Guid Id { get; set; }
        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>The description.</value>
        public virtual string Description { get; set; }
        /// <summary>
        /// Gets or sets the street.
        /// </summary>
        /// <value>The street.</value>
        public virtual string Street { get; set; }
        /// <summary>
        /// Gets or sets the district.
        /// </summary>
        /// <value>The district.</value>
        public virtual string District { get; set; }
        /// <summary>
        /// Gets or sets the city.
        /// </summary>
        /// <value>The city.</value>
        public virtual string City { get; set; }
        /// <summary>
        /// Gets or sets the county.
        /// </summary>
        /// <value>The county.</value>
        public virtual string County { get; set; }
        /// <summary>
        /// Gets or sets the postal code.
        /// </summary>
        /// <value>The postal code.</value>
        public virtual string PostalCode { get; set; }
        /// <summary>
        /// Gets or sets the complements.
        /// </summary>
        /// <value>The complements.</value>
        public virtual string Complements { get; set; }
        /// <summary>
        /// Gets or sets the neighbourhood.
        /// </summary>
        /// <value>The neighbourhood.</value>
        public virtual string Neighbourhood { get; set; }
        /// <summary>
        /// Gets or sets the municipality.
        /// </summary>
        /// <value>The municipality.</value>
        public virtual string Municipality { get; set; }
        /// <summary>
        /// Gets or sets the state.
        /// </summary>
        /// <value>The state.</value>
        public virtual string State { get; set; }
        /// <summary>
        /// Gets or sets the apartment.
        /// </summary>
        /// <value>The apartment.</value>
        public virtual string Apartment { get; set; }
        /// <summary>
        /// Gets or sets the country.
        /// </summary>
        /// <value>The country.</value>
        public virtual Country Country { get; set; }

        #region ToString

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return string.Format("{0}, {1}, {2}, {3}", Street, City, State, Country);
        }

        #endregion

        #region Equality

        /// <summary>
        /// Equalses the specified other.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        public virtual bool Equals(Address other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other.Id.Equals(Id);
        }

        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj)
        {
            return Equals(obj as Address);

        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator ==(Address left, Address right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator !=(Address left, Address right)
        {
            return !Equals(left, right);
        }

        #endregion
    }
}
